package com.mengniu.commerce.sync.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mengniu.commerce.common.core.domain.R;
import com.mengniu.commerce.common.core.enums.ModuleEnum;
import com.mengniu.commerce.common.core.enums.SourceEnum;
import com.mengniu.commerce.common.core.utils.StringUtils;
import com.mengniu.commerce.common.template.enums.APIUrlEnum;
import com.mengniu.commerce.sync.api.domain.MemberInsertModel;
import com.mengniu.commerce.sync.api.domain.MemberModifyModel;
import com.mengniu.commerce.sync.api.domain.MemberRegisterModel;
import com.mengniu.commerce.sync.api.dto.RetryDTO;
import com.mengniu.commerce.sync.common.constant.ApiVersionConstants;
import com.mengniu.commerce.sync.common.constant.CodeConstants;
import com.mengniu.commerce.sync.common.constant.OperationUnitTypeConstants;
import com.mengniu.commerce.sync.common.utils.RestTemplateUtil;
import com.mengniu.commerce.sync.exception.RetryException;
import com.mengniu.commerce.sync.mapper.MemberInfoMapper;
import com.mengniu.commerce.sync.model.MemberInfoModel;
import com.mengniu.commerce.sync.service.MemberService;
import com.mengniu.commerce.sync.utils.RetryUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.RetryContext;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.support.RetrySynchronizationManager;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 会员相关实现类
 */
@Service
@Slf4j
public class MemberServiceImpl implements MemberService {

    public static final String baseURL = "https://t-openapi-gateway.mengniu.cn/";
    @Resource
    private RestTemplateUtil restTemplateUtil;
    @Resource
    private MemberInfoMapper memberInfoMapper;

    @Resource
    private RetryUtils retryUtils;

    /**
     * 会员修改同步蒙牛
     * @param memberModifyModel
     * @return
     */
    @Override
    @Retryable(value = { RetryException.class }, maxAttempts = 8, backoff = @Backoff(delay = 10000))
    public R memberModify(MemberModifyModel memberModifyModel, RetryDTO retryDTO) {
        log.info("会员修改实现类入参{}",JSONObject.toJSONString(memberModifyModel));
        RetryContext context = RetrySynchronizationManager.getContext();
        log.info("当前会员修改重试次数{}",JSONObject.toJSONString(context));
        //第一次重试时将数据落库
        QueryWrapper<MemberInfoModel> mobileWrapper = new QueryWrapper<MemberInfoModel>()
                .eq("mobile", memberModifyModel.getMobile());
        MemberInfoModel memberInfoModel = memberInfoMapper.selectVoOne(mobileWrapper);
        memberInfoMapper.updateById(memberInfoModel);
        //组装固定参数
        JSONObject param = (JSONObject) JSON.toJSON(memberModifyModel);
        restTemplateUtil.constant(param, memberModifyModel.getOperationUnitType(), ApiVersionConstants.V_2_0);
        log.info("调用蒙牛会员修改参数为{}",JSONObject.toJSONString(param));
        JSONObject result;
        try{
            int a = 10 / 0 ;
            result = restTemplateUtil.doPost(param, baseURL + APIUrlEnum.MEMBER_MODIFY.getPath());
            log.info("调用蒙牛会员修改响应为{}",JSONObject.toJSONString(result));
        }catch (Exception e){
            log.error("调用蒙牛会员修改接口失败",e);
            Long id = retryUtils.insertOrUpdate(param, retryDTO.getSource(), retryDTO.getStoreName(), ModuleEnum.MEMBER.getModuleName(), APIUrlEnum.MEMBER_MODIFY.getMethod(), context.getRetryCount(), e.getMessage(),retryDTO.getRetryId());
            retryDTO.setRetryId(id);
            throw new RetryException("发生了重试异常{}", e);
        }
        return Optional.ofNullable(result)
                .filter(res -> res.getInteger("code").equals(CodeConstants.SUCCESS_CODE))
                .map(res -> R.fail(res, "调用蒙牛会员修改接口失败"))
                .orElseGet(() -> {
                    this.updateMemberInfoModel(result,memberInfoModel);
                    memberInfoMapper.updateById(memberInfoModel);
                    return R.ok(result);
                });
    }

    @Override
    @Retryable(value = { RetryException.class }, maxAttempts = 8, backoff = @Backoff(delay = 10000))
    public R memberRegister(MemberRegisterModel memberRegisterModel, RetryDTO retryDTO, String userId) {
        log.info("会员注册实现类入参{}",JSONObject.toJSONString(memberRegisterModel));
        RetryContext context = RetrySynchronizationManager.getContext();
        log.info("当前会员实现重试次数{}",JSONObject.toJSONString(context));
        JSONObject param = (JSONObject) JSON.toJSON(memberRegisterModel);
        restTemplateUtil.constant(param, OperationUnitTypeConstants.MN_QY_MEMBER, ApiVersionConstants.V_2_0);
        log.info("调用蒙牛会员注册参数为{}",JSONObject.toJSONString(param));
        JSONObject result;
        try{
            result = restTemplateUtil.doPost(param, baseURL + APIUrlEnum.MEMBER_REGISTER.getPath());
            log.info("调用蒙牛会员注册响应为{}",JSONObject.toJSONString(result));
        }catch (Exception e){
            log.error("调用蒙牛会员注册接口失败",e);
            Long id = retryUtils.insertOrUpdate(param, retryDTO.getSource(), retryDTO.getStoreName(), ModuleEnum.MEMBER.getModuleName(), APIUrlEnum.MEMBER_REGISTER.getMethod(), context.getRetryCount(), e.getMessage(),retryDTO.getRetryId());
            retryDTO.setRetryId(id);
            throw new RetryException("发生了重试异常{}", e);
        }
        if (Objects.nonNull(result) && !result.getInteger("code").equals(CodeConstants.SUCCESS_CODE)){
            return R.fail(result, "调用蒙牛会员修改接口失败");
        }
        MemberInfoModel model = createMemberInfoModel(result, memberRegisterModel, retryDTO.getSource(), userId);
        int id = memberInfoMapper.insert(model);
        return R.ok(result);
    }

    @Override
    public R memberInsert(List<MemberInsertModel> memberInsertModelList) {
        log.info("存量会员批量同步入参{}",JSONObject.toJSONString(memberInsertModelList));
        memberInsertModelList.forEach(memberInsertModel -> {
            MemberRegisterModel memberRegisterModel = memberInsertModel.getMemberRegisterModel();
            R r = this.memberRegister(memberRegisterModel, memberInsertModel.getRetryDTO(), memberInsertModel.getUserId());
            log.info("单个会员注册参数以及结果{}__{}",JSONObject.toJSONString(memberRegisterModel),JSONObject.toJSONString(r));
        });
        return R.ok();
    }


    public void updateMemberInfoModel(JSONObject data,MemberInfoModel memberInfoModel){
        if (StringUtils.isNotEmpty(data.getString("name"))){
            memberInfoModel.setName(data.getString("name"));
        }
        if (StringUtils.isNotEmpty(data.getString("nickName"))){
            memberInfoModel.setNickName(data.getString("nickName"));
        }
        if (StringUtils.isNotEmpty(data.getString("sex"))){
            memberInfoModel.setSex(data.getInteger("sex"));
        }
        if (StringUtils.isNotEmpty(data.getString("name"))){
            memberInfoModel.setName(data.getString("name"));
        }
        if (StringUtils.isNotEmpty(data.getString("openId"))){
            memberInfoModel.setOpenId(data.getString("openId"));
        }
        if (StringUtils.isNotEmpty(data.getString("unionId"))){
            memberInfoModel.setUnionId(data.getString("unionId"));
        }
        if (StringUtils.isNotEmpty(data.getString("province"))){
            memberInfoModel.setProvince(data.getString("province"));
        }
        if (StringUtils.isNotEmpty(data.getString("city"))){
            memberInfoModel.setCity(data.getString("city"));
        }
        if (StringUtils.isNotEmpty(data.getString("avatar"))){
            memberInfoModel.setAvatar(data.getString("avatar"));
        }
        memberInfoModel.setUpdateTime(new Date());
    }

    public MemberInfoModel createMemberInfoModel(JSONObject data,MemberRegisterModel memberRegisterModel,String source,String userId){
        MemberInfoModel memberInfoModel = new MemberInfoModel();
//        memberInfoModel.setId(new IdGeneratorSnowflake().snowflakeId());
        if (source.equals(SourceEnum.YZ.getSource())){
            memberInfoModel.setYzUserId(userId);
        }
        if (source.equals(SourceEnum.WM.getSource())){
            memberInfoModel.setWmUserId(userId);
        }
        String mnUserId = data.getString("data");
        memberInfoModel.setMnUserId(mnUserId);
        memberInfoModel.setSource(source);
        memberInfoModel.setMobile(memberRegisterModel.getMobile());
        memberInfoModel.setOperationUnitType(OperationUnitTypeConstants.MN_QY_MEMBER);
        memberInfoModel.setName(memberRegisterModel.getName());
        memberInfoModel.setBirthday(memberRegisterModel.getBirthday());
        memberInfoModel.setSex(memberRegisterModel.getSex());
        memberInfoModel.setOpenId(memberRegisterModel.getOpenId());
        memberInfoModel.setUnionId(memberRegisterModel.getUnionId());
        memberInfoModel.setNickName(memberRegisterModel.getNickName());
        memberInfoModel.setProvince(memberRegisterModel.getProvince());
        memberInfoModel.setCity(memberRegisterModel.getCity());
        memberInfoModel.setAvatar(memberRegisterModel.getAvatar());
        memberInfoModel.setCreateTime(new Date());
        return memberInfoModel;
    }





}
